Currently if one tries to execute VMX instruction from inside the
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 11 Mar 2006 09:47:55 +0000 (10:47 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 11 Mar 2006 09:47:55 +0000 (10:47 +0100)
VMX guest, the Xen hyper visor has no handling of it resulting in a
bug(). This patch handles such VMX instructions from the guest returning
invalid opcode to the guest. Also the macro VMX_INVALID_ERROR_CODE is
renamed to the more meaningful VMX_DELIVER_NO_ERROR_CODE.

Signed-Off-By: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-Off-By: Jun Nakajima <jun.nakajima@intel.com>=20
xen/arch/x86/hvm/svm/intr.c
xen/arch/x86/hvm/vmx/io.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/support.h
xen/include/asm-x86/hvm/vmx/vmx.h

index 33f1c42c0637813e93dd6c21e563b18762191ec7..430cad9372499103ceae8ee9b380dfff3874035e 100644 (file)
@@ -187,7 +187,7 @@ asmlinkage void svm_intr_assist(void)
             }
             /* let's inject this interrupt */
             TRACE_3D(TRC_VMX_INT, v->domain->domain_id, intr_vector, 0);
-            svm_inject_extint(v, intr_vector, VMX_INVALID_ERROR_CODE);
+            svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
             interrupt_post_injection(v, intr_vector, intr_type);
             break;
         case VLAPIC_DELIV_MODE_SMI:
index 38ffa0a5d1b54463a12ca7745fb322444ccff2e9..4727d65feeff8b6f7cfe3edef6bc37fa1392556d 100644 (file)
@@ -165,7 +165,7 @@ asmlinkage void vmx_intr_assist(void)
     case VLAPIC_DELIV_MODE_EXT:
     case VLAPIC_DELIV_MODE_FIXED:
     case VLAPIC_DELIV_MODE_LPRI:
-        vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE);
+        vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
         TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
         break;
     case VLAPIC_DELIV_MODE_SMI:
index ac169265f410b6d403dd22715a4402b040f1046b..73037cc0d0058a2f7ae6468951e6faf05d071b88 100644 (file)
@@ -1917,7 +1917,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
     /* don't bother H/W interrutps */
     if (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT &&
         exit_reason != EXIT_REASON_VMCALL &&
-        exit_reason != EXIT_REASON_IO_INSTRUCTION)
+        exit_reason != EXIT_REASON_IO_INSTRUCTION) 
         HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
 
     if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
@@ -2052,6 +2052,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
         __update_guest_eip(inst_len);
         break;
     }
+#if 0 /* keep this for debugging */
     case EXIT_REASON_VMCALL:
         __get_instruction_length(inst_len);
         __vmread(GUEST_RIP, &eip);
@@ -2060,6 +2061,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
         hvm_print_line(v, regs.eax); /* provides the current domain */
         __update_guest_eip(inst_len);
         break;
+#endif
     case EXIT_REASON_CR_ACCESS:
     {
         __vmread(GUEST_RIP, &eip);
@@ -2100,6 +2102,21 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
     case EXIT_REASON_MWAIT_INSTRUCTION:
         __hvm_bug(&regs);
         break;
+    case EXIT_REASON_VMCALL:
+    case EXIT_REASON_VMCLEAR:
+    case EXIT_REASON_VMLAUNCH:
+    case EXIT_REASON_VMPTRLD:
+    case EXIT_REASON_VMPTRST:
+    case EXIT_REASON_VMREAD:
+    case EXIT_REASON_VMRESUME:
+    case EXIT_REASON_VMWRITE:
+    case EXIT_REASON_VMOFF:
+    case EXIT_REASON_VMON:
+        /* Report invalid opcode exception when a VMX guest tries to execute 
+            any of the VMX instructions */
+        vmx_inject_exception(v, TRAP_invalid_op, VMX_DELIVER_NO_ERROR_CODE);
+        break;
+
     default:
         __hvm_bug(&regs);       /* should not happen */
     }
index b6f22e09adbac7540d1408bc5e96d113e41913b7..043754546a31a7b1e52e452a2fb145743d7c2258 100644 (file)
@@ -99,7 +99,7 @@ enum hval_bitmaps {
 
 #define PC_DEBUG_PORT   0x80
 
-#define VMX_INVALID_ERROR_CODE  -1
+#define VMX_DELIVER_NO_ERROR_CODE  -1
 
 /*
  * This works for both 32bit & 64bit eflags filteration
index b5a4ced87f9781caa8aa49b43893d8189477d500..f4429f3dbe5b4c2c9a264fa4d9628e208373b8dd 100644 (file)
@@ -119,7 +119,15 @@ extern unsigned int cpu_rev;
 #define EXIT_REASON_RDPMC               15
 #define EXIT_REASON_RDTSC               16
 #define EXIT_REASON_VMCALL              18
-
+#define EXIT_REASON_VMCLEAR             19
+#define EXIT_REASON_VMLAUNCH            20
+#define EXIT_REASON_VMPTRLD             21
+#define EXIT_REASON_VMPTRST             22
+#define EXIT_REASON_VMREAD              23
+#define EXIT_REASON_VMRESUME            24
+#define EXIT_REASON_VMWRITE             25
+#define EXIT_REASON_VMOFF               26
+#define EXIT_REASON_VMON                27
 #define EXIT_REASON_CR_ACCESS           28
 #define EXIT_REASON_DR_ACCESS           29
 #define EXIT_REASON_IO_INSTRUCTION      30
@@ -425,7 +433,7 @@ static inline int __vmx_inject_exception(struct vcpu *v, int trap, int type,
 
     /* Reflect it back into the guest */
     intr_fields = (INTR_INFO_VALID_MASK | type | trap);
-    if (error_code != VMX_INVALID_ERROR_CODE) {
+    if (error_code != VMX_DELIVER_NO_ERROR_CODE) {
         __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
         intr_fields |= INTR_INFO_DELIEVER_CODE_MASK;
      }
@@ -455,7 +463,7 @@ static inline int vmx_reflect_exception(struct vcpu *v)
     if (vector & INTR_INFO_DELIEVER_CODE_MASK)
         __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
     else
-        error_code = VMX_INVALID_ERROR_CODE;
+        error_code = VMX_DELIVER_NO_ERROR_CODE;
     vector &= 0xff;
 
 #ifndef NDEBUG